package gui;
import java.awt.*;
//import java.awt.event.*;
import javax.swing.*;
//import javax.swing.event.*;

import register.Register;

/**
 * Creates a plot of the probabilities of each  potential quantum state of the register. 
 * Extends JPanel.
 * @author James Hancox
 * 
 *
 */
public class ProbPlot extends JPanel{
	
	private static final long serialVersionUID = 1L;
	/**Number of states in register.*/
	private int numStates;
	private Register reg;
	
	/**Creates a plot of the probabilities of each states.
	 * @param width Width of the plot area.*/
	public ProbPlot (int width){
		setSize(width,500);
		setDoubleBuffered(true);
		setBackground(Color.white);
		setBorder(BorderFactory.createTitledBorder("Probabilities"));
		setVisible(true);
		//setOpaque(true);
	}
	
	/**Sets up the plot area.
	 * 
	 * @param reg Register being plotted.
	 */
	public void setup(Register reg){
		this.reg=reg;
		this.numStates = reg.getNumStates();
		repaint();
	}
	
	/**Method to draw the probabilities panel.*/
	public void paintComponent (Graphics g){
			super.paintComponent(g);
			Dimension d = getSize();
			/*Height of the plotting area.*/
			double height = d.height -60;
			/*height of horizontal line*/
			double lineHeight;
			/*Horizontal position of vertical line*/
			double lineX;
			/*Y-axis label*/
			double yLabel = 0.0;
			/*X-axis label*/
			int xLabel = 0;
			/*Width of the plotting area.*/
			double width = d.width -60;
			/*Width of the bars on the barchart.*/
			double barWidth = width/numStates;
			/*Height of the bar; changes for each bar. Is set within the for loop later.*/
			int barHeight;
			g.setColor(Color.black);
			
			//drawing horizontal gridlines and Y-axis labels
			for (int i = 0;i<=10;i++){
				if(i>0 && i<10){
					g.setColor(Color.lightGray);
				}
				/*determined as a double, then rounded to an int; prevents rounding issues earlier on*/
				lineHeight = i*(height/10) + 30;
				g.drawLine(30, (int)lineHeight, (int) width + 30, (int) lineHeight);
				g.setColor(Color.black);
				/*use substring() to lop off the end of the double, fixes most rounding issues.*/
				String labelString = Double.toString(1.0-yLabel).substring(0,3);
				/*cheating way to deal with rounding error. Need a better solution tbh.*/
				if(i==10){
					labelString="0.0";
				}
				g.drawString(labelString, 10,(int)lineHeight);
				yLabel += 0.1;
			}
			
			//drawing vertical gridlines and x-axis labels
			for (int i=0;i<=8;i++){
				if(i>0 && i<8){
					g.setColor(Color.lightGray);
				}
				lineX = i*(width/8)+30;
				/*draw gridlines*/
				g.drawLine((int)lineX, 30, (int)lineX,(int) height +30);
				g.setColor(Color.black);
				/*draw labels*/
				g.drawString(" " + xLabel,(int)lineX - 10,(int)height+45);
				xLabel += numStates/8;
			}
			//drawing "States" label
			g.drawString("State", (int) width/2,(int)height+55 );
			
			//drawing probability bars
			g.setColor(Color.magenta);
			for (int i = 0;i<numStates;i++){
				barHeight = (int)(height*reg.getProbabilityOfState(i));
				//can't just use i*barWidth due to rounding errors when barWidth<1.
				double xPos = i*width/numStates;
				if(barWidth>=2){
					g.fillRect((int)(i*barWidth) + 30, (int) height - barHeight +30 , (int)barWidth, barHeight);
				}
				//if line is narrower than 2 pixels, the width is fixed at 2 pixels; ensures line always
				//displays no matter what. Minor overlapping issues, but we'll only have one large line. 
				else{
					g.fillRect((int)xPos +30 , (int)height - barHeight +30, 2 , barHeight);
				}
			}
	 }
	
	/**Redraws the probabilities panel.*/
	public void update(){
		repaint();
	}
	
	/**Resets the panel.*/
	public void reset(){
		repaint();
	}
}